#ifndef RTU_SLAVE_HPP
#define RTU_SLAVE_HPP

#include <cstdint>
#include "ModbusSlave.hpp"

namespace Modbus {

class RTUSlave : public Slave {
public:
    class PortableStrategy : public Slave::PortableStrategy {
    public:
        virtual int send(void *frame,unsigned int size) = 0;
    };

    struct Configuration {
        unsigned int address;
        uint8_t *tx_buffer;
        unsigned int tx_buffer_size;
        uint8_t *rx_buffer;
        unsigned int rx_buffer_size;
    };

    class Result : public Slave::Result {
    public:
        static const int BUFFER_IS_TOO_SMALL = -101;
        static const int PDU_SIZE_OVER_BUFFER_SIZE = -102;
        static const int INVALID_DATA_ADDRESS = -1002;
        static const int INVALID_DATA_VALUE = -1003;
        static const int DEVICE_FAULT = -1004;
        static const int DEVICE_BUSY = -1007;
    };
public:
    explicit RTUSlave(PortableStrategy *portable,Configuration configuration);
    virtual ~RTUSlave() = default;

    virtual int setAddress(unsigned int address);
    virtual int getAddress(unsigned int *address_buffer);

    virtual int sendResponse(void *pdu,unsigned int size);

    virtual int feed(uint8_t byte);
    virtual int cut(void);
protected:
    PortableStrategy *portable_strategy = nullptr;
    Configuration configuration;
    unsigned int rx_size = 0;
};

}

#endif
